package com.archway.appframe.web;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.archway.appframe.frame.AppframeBusiConfig;
import com.archway.appframe.task.AppframeTaskConfig;
import com.archway.appframe.web.interceptor.DefaultSecurityInterceptor;
import com.archway.appframe.web.interceptor.DefaultSessionInterceptor;



/**
 * 
 * <strong>(please edit it when context changed)</strong></br>
 * <h1>描述:</h1>
 * <li>注解@ComponentScan 使扫描项目中所有mvc目录下注解为@Controller 的 类</li>
 * <li>注解@EnableWebMvc 相当于 mvc:annotation-driven ，用于开启 如 JSR-303校验支持  、<B>信息转换</B>  或者 对域格式化的支持</li>
 * @author lirn 
 * @createDate 2014年3月6日 上午12:09:10 </br>
 * @copyright Copyright (c) 2014 by lirongnian. All rights reserved. 
 * 
 */
@Configuration
@ComponentScan(basePackages={"com.archway.**.mvc"} //项目下所有mvc层
				,includeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class)})
@Import(value = {AppframeSessionConfig.class,	//session控制，如果有的话
					AppframeBusiConfig.class,	//项目导入业务层配置
					/*AppframeTaskConfig.class*/})	//任务层，也可考虑放入业务层
@EnableWebMvc
public class AppframeWebMVCConfig /*前端控制器配置类*/
			extends WebMvcConfigurerAdapter /*内部都为空实现，用于改写WebMvcConfigurer的默认实现*/{

	/*
	 * 
	 * <strong>(please edit it when context changed)</strong></br>
	 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#configureDefaultServletHandling(org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer)
	 * <h1>描述:</h1>
	 * <li>为了解决静态资源访问被拦截的问题</li> 
	 * <li>等同于<mvc:default-servlet-handler/>配置 </li> 
	 * <li>此 tag 允许将 DispatcherServlet 映射到 “/” (因此重写容器默认Servlet的映射)，
	 * 	         虽然仍然允许容器默认的Servlet处理静态资源请求。
	 *     它配置了一个 DefaultServletHttpRequestHandler 
	 *     使 URL 映射 “/**” 并且相对于其他URL映射优先级最低。 </li> 
	 * @author lirn
	 * @createDate 2014年3月12日 上午1:08:39
	 */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    	configurer.enable();
    }
    
    
    /*
     * 
     * <strong>(please edit it when context changed)</strong></br>
     * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addInterceptors(org.springframework.web.servlet.config.annotation.InterceptorRegistry)
     * <h1>描述:拦截器</h1>
     * <li>描述细节列表</li> 
     * <li>描述细节列表</li> 
     * @author lirn
     * @createDate 2014年3月24日 下午10:53:35
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	registry.addInterceptor(new DefaultSecurityInterceptor());
    	registry.addInterceptor(new DefaultSessionInterceptor());
    	super.addInterceptors(registry);
    }
    
    

    
	/**
	 * 
	 * <strong>(please edit it when context changed)</strong></br>
	 * <h1>描述:</h1>
	 * <li>用户请求映射器，里面可以设置拦截器等特性</li> 
	 * @return
	 * @author lirn
	 * @createDate 2014年3月6日 上午12:08:29
	 */
	@Bean
	RequestMappingHandlerMapping getHandlerMapping(){
		RequestMappingHandlerMapping rmdm = new RequestMappingHandlerMapping();
		return rmdm;
	}
	
	/**
	 * 
	 * <strong>(please edit it when context changed)</strong></br>
	 * <h1>描述:</h1>
	 * <li>设置数据转换器，可以添加多个转换器</li> 
	 * <li>描述细节列表</li>  
	 * @return
	 * @author lirn
	 * @createDate 2014年3月6日 上午12:06:44
	 */
	@Bean
	RequestMappingHandlerAdapter getHandlerAdapter(){
		RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
		
		/**处理请求************/
		//List<HandlerMethodArgumentResolver> handlerMethodArgumentResolverList = new ArrayList<HandlerMethodArgumentResolver>();
		//handlerMethodArgumentResolverList.add(this.getJsonArgumentInterceptor());//拦截器
		//adapter.setArgumentResolvers(handlerMethodArgumentResolverList);
		//adapter.setArgumentResolvers(handlerMethodArgumentResolverList);
		//adapter.setCustomArgumentResolvers(handlerMethodArgumentResolverList);
		/**处理响应*****************/
		List<HttpMessageConverter<?>> httpMessageConverterList = new ArrayList<HttpMessageConverter<?>>();
		httpMessageConverterList.add(this.getJsonMessageConverter());
		//httpMessageConverterList.add(this.getMediaTypeConverter());

		
		//httpMessageConverterList.add(index, element);
		//增加 多个，比如再支持一个xml的httpMessageConverterList.add(支持xml的converter);
		adapter.setMessageConverters(httpMessageConverterList);
		
		//adapter.getMessageConverters().add(this.getJsonMessageConverter());
		//adapter.setMessageConverters(httpMessageConverterList); //展示器 当前通过json实现
		return adapter;
	}




	/**
	 * 
	 * <strong>(please edit it when context changed)</strong></br>
	 * <h1>描述:</h1>
	 * <li>json请求</li> 
	 * <li>描述细节列表</li>  
	 * @return
	 * @author lirn
	 * @createDate 2014年3月21日 上午1:49:51
	 */
//	@Bean
//	HandlerMethodArgumentResolver getJsonArgumentInterceptor() {
//		//RequestRichParamMethodArgumentResolver resolver = new RequestRichParamMethodArgumentResolver();
//		return resolver;
//	};
	
	
	
	
	
	/**
	 * 
	 * <strong>(please edit it when context changed)</strong></br>
	 * <h1>描述:</h1>
	 * <li>json转换器</li> 
	 * @return
	 * @author lirn
	 * @createDate 2014年3月6日 上午12:08:04
	 */
	
	MappingJackson2HttpMessageConverter getJsonMessageConverter() {
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
		List<MediaType> supportedMediaTypeList = new ArrayList<MediaType>();
		/**
		 * 需要说明的是，发现post方式只支持x-www-form-urlencoded 详见 @see boolean org.springframework.http.server.ServletServerHttpRequest.isFormPost(HttpServletRequest request)
		 */
		supportedMediaTypeList.add(new MediaType("application", "x-www-form-urlencoded"));
		supportedMediaTypeList.add(new MediaType("application", "json", Charset.forName("UTF-8"))); //response 会用到
		supportedMediaTypeList.add(new MediaType("application", "*+json",Charset.forName("UTF-8")));
		return converter;
	};
	
	
	private ByteArrayHttpMessageConverter getMediaTypeConverter() {
		ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
		//converter.setSupportedMediaTypes(supportedMediaTypes);
		return converter;
	}
}
